const express = require('express');
const multer = require('multer');
const fs = require('fs');
const path = require('path');
const cors = require('cors');
const { promisify } = require('util');

// 转换为Promise风格的文件操作
const fsWriteFile = promisify(fs.writeFile);
const fsReadFile = promisify(fs.readFile);
const fsMkdir = promisify(fs.mkdir);
const fsUnlink = promisify(fs.unlink);
const fsExists = (path) => new Promise(resolve => fs.exists(path, resolve));

// 初始化Express应用
const app = express();
const PORT = 3005;

// 配置中间件
app.use(cors());
app.use(express.json());
app.use(express.urlencoded({ extended: true }));

// 配置存储目录
const UPLOAD_DIR = path.resolve(__dirname, 'uploads');
const TEMP_DIR = path.resolve(__dirname, 'temp');

// 确保目录存在
[UPLOAD_DIR, TEMP_DIR].forEach(dir => {
    if (!fs.existsSync(dir)) {
        fs.mkdirSync(dir, { recursive: true });
    }
});

// 配置multer用于处理文件上传
const storage = multer.diskStorage({
    destination: (req, file, cb) => {
        // 为每个文件创建单独的临时目录
        const fileMd5 = req.body.fileMd5;
        const tempDir = path.join(TEMP_DIR, fileMd5);
        
        if (!fs.existsSync(tempDir)) {
            fs.mkdirSync(tempDir, { recursive: true });
        }
        
        cb(null, tempDir);
    },
    filename: (req, file, cb) => {
        // 使用分片索引作为文件名
        cb(null, req.body.chunk);
    }
});

const upload = multer({ storage });

// 分片上传接口
app.post('/upload/chunk', upload.single('file'), async (req, res) => {
    try {
        const { chunk, chunks, fileMd5, fileName } = req.body;
        
        console.log(`收到分片: ${chunk}/${chunks}, 文件标识: ${fileMd5}`);
        
        res.json({
            success: true,
            message: `分片 ${chunk} 上传成功`
        });
    } catch (error) {
        console.error('分片上传失败:', error);
        res.status(500).json({
            success: false,
            message: '分片上传失败: ' + error.message
        });
    }
});

// 合并分片接口
app.post('/upload/merge', async (req, res) => {
    try {
        const { fileMd5, fileName, chunks } = req.body;
        
        if (!fileMd5 || !fileName || !chunks) {
            return res.status(400).json({
                success: false,
                message: '缺少必要参数'
            });
        }
        
        console.log(`开始合并分片: ${fileMd5}, 共${chunks}个分片`);
        
        // 分片存储目录
        const tempDir = path.join(TEMP_DIR, fileMd5);
        const targetPath = path.join(UPLOAD_DIR, fileName);
        
        // 检查临时目录是否存在
        if (!await fsExists(tempDir)) {
            return res.status(400).json({
                success: false,
                message: '未找到分片文件'
            });
        }
        
        // 合并所有分片
        for (let i = 0; i < chunks; i++) {
            const chunkPath = path.join(tempDir, i.toString());
            
            // 检查分片是否存在
            if (!await fsExists(chunkPath)) {
                return res.status(400).json({
                    success: false,
                    message: `缺少分片 ${i}`
                });
            }
            
            // 读取分片内容并追加到目标文件
            const chunkData = await fsReadFile(chunkPath);
            await fsWriteFile(targetPath, chunkData, { flag: 'a' });
            
            // 删除已合并的分片
            await fsUnlink(chunkPath);
        }
        
        // 删除临时目录
        fs.rmdirSync(tempDir, { recursive: true });
        
        console.log(`文件合并完成: ${fileName}`);
        
        res.json({
            success: true,
            message: '文件合并成功',
            fileName,
            filePath: `/uploads/${fileName}`,
            size: fs.statSync(targetPath).size
        });
    } catch (error) {
        console.error('分片合并失败:', error);
        res.status(500).json({
            success: false,
            message: '分片合并失败: ' + error.message
        });
    }
});

// 静态文件服务
app.use('/uploads', express.static(UPLOAD_DIR));

// 启动服务器
app.listen(PORT, () => {
    console.log(`服务器运行在 http://localhost:${PORT}`);
    console.log(`上传的文件将保存在: ${UPLOAD_DIR}`);
});
